package edu.uiowa.ms.hsm;

import java.util.*;

import edu.uiowa.ms.hsm.dijkstra.model.*;
import edu.uiowa.ms.hsm.dijkstra.engine.*;

public class RandomSolution extends Solution {
	
	/**
	 * Random solution constructor.
	 * 
	 * @param	num_routes		number of routes
	 * @param	max_stops		maximum number of stops
	 * @param	min_stops		minimum number of stops
	 * @param	d				demand matrix
	 * @param	t				time (cost) matrix
	 * @param	road_network	our road network in graph form
	 */
	public RandomSolution(int num_routes, int max_stops, int min_stops, int[][] d, int[][] t, Graph road_network) {
		
		//Initialize basic solution attributes
		super(num_routes, max_stops, min_stops, d, t, road_network);
		
		/*
		//PRINT TIME MATRIX:
		for (int i = 0; i < time[0].length; i++) {
			for (int j = 0; j < time[0].length; j++)
				System.out.print(time[i][j] + "\t");
			System.out.println();
		}
		
		int[] route_length = new int[numRoutes];
		
		Set <Integer> routes = new HashSet<Integer>();
		for(int route = 0; route < num_routes; route++){
			routes.add(route);
		}
		*/
		Random rand = new Random();
		
		//Add all vertices to free stops, remove when they are added to routes
		for(int i = 0; i < numStops; i++){
			freeStops.add(i);
		}
		
		//Randomly generate route in a greedy fashion
		//  Randomly choose source and destination nodes
		//  Find shortest path between them
		//System.out.println("FREE STOPS BEFORE: " + freeStops);
		List <Edge> paths = new ArrayList<Edge>();
		List <Vertex> stops = roadNetwork.getVertexes();
		for (int i = 0; i < numRoutes; i++) {
			int randS = 0, randD = 0;
			while (randS == randD) {
				randS = rand.nextInt(numStops);
				randD = rand.nextInt(numStops);
			}
			DijkstraAlgorithm dijkstraAlg = new DijkstraAlgorithm(roadNetwork);
			Vertex source = roadNetwork.getVertexes().get(randS);
			Vertex destination = roadNetwork.getVertexes().get(randD);
			
			//System.out.println(source.toString() + "  TO  " + destination.toString());
			
			dijkstraAlg.execute(source);
			//System.out.println(dijkstraAlg.predecessors);
			LinkedList<Vertex> path = dijkstraAlg.getPath(destination);
			
			int j = 0;
			Vertex previous = source;
			/*
			System.out.println("=====");
			System.out.println("vertices = " + roadNetwork.getVertexes().toString() + " edes = " + roadNetwork.getEdges().toString());
			System.out.println("Source = " + source.toString() + " Destination = " + destination.toString());
			System.out.println("Path = " + path);
			System.out.println("Preds = " + dijkstraAlg.predecessors);
			*/
			for (Vertex vertex : path){
				//System.out.print(vertex + "  ");
				int stop = Integer.parseInt(vertex.toString());
				List <Integer> fs = new ArrayList <Integer>();//*HACK*
				fs.add(stop);
				freeStops.removeAll(fs);//.remove defaults to removing index but we want it to remove int
				solution[i][j] = stop;
				j++;
				//System.out.println("NEW EDGE: " +previous.toString() +  " -> " + vertex.toString());
				if (!vertex.equals(source)){
					paths.add(new Edge(Integer.toString((i*numStops)+j), previous, vertex, time[Integer.parseInt(previous.getName())][Integer.parseInt(vertex.getName())]));
					paths.add(new Edge(Integer.toString((j*numStops)+i), vertex, previous, time[Integer.parseInt(vertex.getName())][Integer.parseInt(previous.getName())]));
				}
				previous = vertex;
			}
		}
		//System.out.println("PATHS = " + paths.toString());
		routeNetwork = new Graph(stops, paths);
		
		//System.out.println("FREE STOPS AFTER: " + freeStops);
		
		
		
		/*
		//ADD STOPS TO ROUTES
		Collections.shuffle(stops); //!!!YOU HAVE TO SHUFFLE FIRST!!!
		Iterator<Integer> stop_iter = stops.iterator();
		while(stop_iter.hasNext()) {
			//Add remaining stops to available routes
			int stop = Integer.parseInt(stop_iter.next().toString());
			int route = rand.nextInt(routes.size());
			
			solution[route][route_length[route]++] = stop;
			//System.out.println("Stop " + stop + " added to route " + route);
		}
		*/
	}	
	

}